package order

import (
	"fmt"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
	"go-papers/constant"
	"go-papers/logic"
	"go-papers/models"
	"go-papers/models/protocols"
	"go-papers/notice"
	"go-papers/pkg/lognew"
	"go-papers/tools"

	"go-papers/tools/app"
)

func PayOrder(c *gin.Context) {
	var pp protocols.OrderPayReq
	err := c.ShouldBindJSON(&pp)
	if err != nil {
		app.CommonResp(c, -1, "参数错误", nil)
		return
	}

	mid := tools.GetMemberId(c)
	if mid == 0 {
		app.CommonResp(c, 126, "请登陆后操作", nil)
		return
	}
	//
	var or models.Order
	or.OrderNo = pp.OrderNo
	orderInfo, err := or.Get()
	if err != nil {
		app.CommonResp(c, -1, "订单记录不存在", nil)
		return
	}

	//订单状态不等于1
	if orderInfo.OrderStatus != constant.ORDER_STATUS_1 && orderInfo.OrderStatus != constant.ORDER_STATUS_5 {
		app.CommonResp(c, -1, "当前订单无法支付", nil)
		return
	}

	wxPay, err := logic.GetPrepayId(c, orderInfo.OrderId, pp.OpenId, true)

	resp := make(map[string]interface{})
	resp["orderId"] = orderInfo.OrderId
	resp["orderNo"] = orderInfo.OrderNo
	resp["orderName"] = orderInfo.OrderName
	if err != nil {
		resp["err_msg"] = err.Error()
	} else {
		resp["err_msg"] = ""
	}
	if wxPay != nil {
		resp["trade_type"] = wxPay.TradeType
		resp["prepay_id"] = wxPay.PrepayId
		resp["code_url"] = wxPay.CodeUrl

		payInfo := make(map[string]interface{})
		// 支付签名时间戳，注意微信jssdk中的所有使用timestamp字段均为小写。 但最新版的支付后台生成签名使用的timeStamp 字段名需大写其中的S字符
		payInfo["timeStamp"] = time.Now().Unix()
		payInfo["nonceStr"] = wxPay.NonceStr // 支付签名随机串，不长于 32 位
		// 统一支付接口返回的prepay_id参数值，提交格式如：prepay_id=\*\*\*）
		payInfo["package"] = "prepay_id=" + wxPay.PrepayId
		// 签名方式，默认为'SHA1'，使用新版支付需传入'MD5'
		payInfo["signType"] = "MD5"
		// 支付签名
		payInfo["paySign"] = logic.GetPaySign(payInfo, "wx")

		resp["pay_info"] = payInfo

	} else {
		resp["trade_type"] = ""
		resp["prepay_id"] = ""
		resp["code_url"] = ""
		resp["pay_info"] = nil
	}

	//用户操作订单记录
	orlog := models.OrderOprateLog{
		OrderId:         orderInfo.OrderId,
		Title:           "用户支付",
		Desc:            "用户支付/" + orderInfo.PayType + "/" + fmt.Sprintf("%.2f", orderInfo.OrderPrice),
		LogType:         "5",
		OrderStatusName: tools.OrderStatusName(orderInfo.OrderStatus),
		PayStatusName:   tools.PayStatusName(orderInfo.PayTime, orderInfo.RefundTime),
		LogName:         "用户支付",
		LogUid:          mid,
	}
	_, _ = orlog.Create() // 用户支付

	app.OK(c, resp, "下单成功，去支付")

}

/**
 * 	确认排课按钮
 */
func SureCheck(c *gin.Context) {
	var data models.Order
	var err error
	if size := c.Request.FormValue("orderId"); size != "" {
		data.OrderId = tools.StrToInt(err, size)
	}
	if data.OrderId == 0 {
		app.ApiResp(c, -1, "订单id orderId 解析异常", nil)
		return
	}
	data.MemberId = tools.GetMemberId(c)
	if data.MemberId == 0 {
		app.CommonResp(c, 126, "请登陆后操作", nil)
		return
	}

	opendId := c.Request.FormValue("openId")

	result, err := data.Get()
	if err != nil || result.OrderId == 0 {
		app.CommonResp(c, -1, "订单记录不存在", nil)
		return
	}
	// 订单是否指定状态
	orderAllowStatus := []string{"10"}
	if !tools.InArrayString(result.OrderStatus, orderAllowStatus) {
		app.CommonResp(c, -1, "订单状态不合法", nil)
		return
	}

	// 处理订单分账 以及 分账佣金记录
	if ok, msg := logic.OrderShareHandle(result.OrderId); !ok {
		app.CommonResp(c, -1, "订单更新失败/刷新试试"+msg, result)
		return
	}

	//操作状态变动
	result.OrderStatus = constant.ORDER_STATUS_20
	result.SureTime = time.Now().Format("2006-01-02 15:04:05")
	result.IsSure = "1"
	nn, err := result.Update(result.OrderId)
	if err != nil {
		app.CommonResp(c, -1, "订单更新失败/刷新试试", result)
		return
	}

	//用户操作订单记录
	orlog := models.OrderOprateLog{
		OrderId:         result.OrderId,
		Title:           "用户确认排课",
		Desc:            "用户确认排课/" + fmt.Sprintf("%.2f", result.OrderPrice) + "/" + opendId,
		LogType:         "5",
		OrderStatusName: tools.OrderStatusName(result.OrderStatus),
		PayStatusName:   tools.PayStatusName(result.PayTime, result.RefundTime),
		LogName:         "用户确认排课",
		LogUid:          data.MemberId,
	}
	_, _ = orlog.Create() // 用户确认排课

	var wg sync.WaitGroup //定义一个同步等待的组
	wg.Add(1)             //为同步等待组增加一个成员
	go func() {

		go notice.MsgOrderSureSuccess2(opendId, result.OrderId) // 用户 用户确认排课

		logic.OrderChangeInfo(result.OrderId) // 确认排课

		defer wg.Done()
	}()

	wg.Wait()

	app.ApiResp(c, 0, "确认成功", nn)

}

/**
 * 	申请退款按钮
 */
func RefundCheck(c *gin.Context) {
	var data models.Order
	var err error
	if size := c.Request.FormValue("orderId"); size != "" {
		data.OrderId = tools.StrToInt(err, size)
	}
	if data.OrderId == 0 {
		app.ApiResp(c, -1, "订单id orderId 解析异常", nil)
		return
	}
	data.MemberId = tools.GetMemberId(c)
	if data.MemberId == 0 {
		app.CommonResp(c, 126, "请登陆后操作", nil)
		return
	}

	result, err := data.Get()
	if err != nil || result.OrderId == 0 {
		app.CommonResp(c, -1, "订单记录不存在", nil)
		return
	}
	// 订单是否指定状态
	orderAllowStatus := []string{"10", "20", "65"}
	if !tools.InArrayString(result.OrderStatus, orderAllowStatus) {
		app.CommonResp(c, -1, "订单状态不合法", nil)
		return
	}

	var refund models.OrderRefund
	info, _ := refund.GetByID(result.OrderId, data.MemberId)
	if info.Id > 0 {
		app.CommonResp(c, -1, "当前订单有一笔退款进行中", nil)
		return
	}

	//退款操作状态变动
	result.OrderStatus = constant.ORDER_STATUS_60
	result.RefundReason = c.Request.FormValue("refundReason")
	nn, err := result.Update(result.OrderId)
	if err != nil {
		app.CommonResp(c, -1, "订单更新失败/刷新试试", result)
		return
	}

	mname := tools.GetMemberName(c)

	//用户操作订单记录
	orlog := models.OrderOprateLog{
		OrderId:         result.OrderId,
		Title:           "用户申请退款",
		Desc:            "用户申请退款/" + result.RefundReason,
		LogType:         "5",
		OrderStatusName: tools.OrderStatusName(result.OrderStatus),
		PayStatusName:   tools.PayStatusName(result.PayTime, result.RefundTime),
		LogName:         "用户申请退款",
		LogUid:          data.MemberId,
	}
	_, _ = orlog.Create() // 用户申请退款

	go notice.NoticeByType(notice.OrderRefund, result.OrderId, data.MemberId, 0) // 用户申请 退款

	//生产退款单记录
	refu := models.OrderRefund{
		OrderId:      result.OrderId,
		OrderName:    result.OrderName,
		UserId:       0,
		UserName:     "",
		MemberId:     result.MemberId,
		MemberName:   mname,
		RefundStatus: "1",
		RefundTime:   "",
		RefundReason: result.RefundReason,
		RefundPrice:  0,
		CheckInfo:    "",
		CheckTime:    "",
	}
	_, err = refu.Create()
	if err != nil {
		lognew.Error(c, "OrderRefundError", lognew.Fields{"err": err.Error(), "data": data})
	}
	app.ApiResp(c, 0, "申请成功", nn)
}
